/**
 * \file    driver.h
 * \brief   Parser generator.
 * \author  Jérôme LAURENS
 * \version 0.1
 * \date    September 23, 2014
 *
 * Reads a LALR(1) grammar, generates a parser based on a template file.
 * This is based on lemon parser generator, but has strongly been
 * revisited.
 *
 */

#ifndef DRIVER_H
#define DRIVER_H

#include "common.h"
#include "builder.h"

LPP_NAMESPACE_BEGIN

class Driver
{
public:
    Driver(Builder const & builder)
        : builder_m(builder) {}
    String const test_rule_names() const;
    StringList const prepared_rule_names() const;
    String const test_prepared_actions() const;
    StringList const prepared_actions() const;
    String const test_lookaheads() const;
    StringList const prepared_lookaheads() const;
    String const test_shift_offsets() const;
    StringList const prepared_shift_offsets() const;
    String const test_reduce_offsets() const;
    StringList const prepared_reduce_offsets() const;
    StringList const prepared_fallbacks() const;
    String const test_symbol_names() const;
    StringList const prepared_symbol_names() const;
    String const test_rule_informations() const;
    StringList const prepared_rule_informations() const;
    StringList const prepared_codes() const;
    StringList const prepared_enum() const;
    GrammarRef const & grammar() const {
        return generator().grammar();
    }
    Generator const & generator() const {
        return builder_m.generator();
    }
    SymbolIndex number_of_lookahead_symbols() const {
        return grammar()->number_of_lookahead_symbols();
    }
    RuleIndex number_of_rules() const {
        return grammar()->number_of_rules();
    }
    Index number_of_states() const {
        return states().size();
    }
    StateRefList const & states() const {
        return generator().states();
    }
    SymbolRef const wildcard_symbol() const {
        return grammar()->wildcard_symbol();
    }
    void prepare_output();
private:
    Builder builder_m;
    std::map<String,StringList> output_m;
    static String Minimum_size_type(long long int lwr, long long int upr);
    static String Minimum_size_type(unsigned long long int upr);
};

LPP_NAMESPACE_END

#endif // DRIVER_H
